Skip to content

feat(runner): complete Fleet enrollment and runner details (RUN-12, RUN-13) - #373

Draft
KafuChino123 wants to merge 38 commits into
masterfrom
feat/run-12-13-runner-details
Draft

feat(runner): complete Fleet enrollment and runner details (RUN-12, RUN-13)#373
KafuChino123 wants to merge 38 commits into
masterfrom
feat/run-12-13-runner-details

Conversation

@KafuChino123

Copy link
Copy Markdown
Member

Summary

  • connect ArcBox Desktop to Fleet Platform and the local Fleet Agent, including device-authorization sign-in, enrollment, recovery, and live state watching
  • add the This Mac runner UI with readiness status, workspace enrollment, and host overview, capacity, settings, and identity tabs
  • add platform-backed job history and selection, job info and runtime details, and GitHub Actions links
  • add Fleet control and platform client packages, generated control bindings, project wiring, and coverage for authentication, enrollment, state mapping, and runner details

Why

RUN-12 and RUN-13 require live Platform and Agent state before host and job details can be presented meaningfully. This change lands the complete dependency chain from authentication through enrollment and Fleet watch state, replacing the earlier sample and manual-enrollment paths.

User impact

Signed-in users can connect this Mac to an ArcBox workspace, monitor runner readiness and recovery states, drain or unenroll the runner, inspect host identity and capacity, browse job history, and open the corresponding GitHub Actions details and logs.

Validation

  • make lint
  • make test — 294 XCTest tests and 70 Swift Testing tests passed with zero failures

KafuChino123 and others added 30 commits July 22, 2026 02:34
Add a FleetControlClient Swift package with generated protobuf and gRPC stubs for the fleet agent local control API.

Wire the local package into the ArcBox app target so phase 1 desktop integration can import the generated client types.
Wrap the generated fleet control stubs in a high-level client for lifecycle, state watch, and settings RPCs.

Map proto responses into desktop-facing models while preserving optional settings update presence semantics, and cover the mapping behavior with tests.
Add the local fleet control client to SwiftUI environment values and app scene injection.

Start the fleet control transport outside daemon startup, log through the fleet category, and close it during app termination.
Drive fleet agent state from the local control watch stream.

Add lifecycle actions, settings updates, reconnect backoff, and user-readable error handling for the runners dashboard.
Consume the signed-in OIDC session to list Platform workspaces and issue workspace-scoped Fleet enrollment tokens.

Wire token issuance into local Fleet Agent enrollment and configure the Platform endpoint for app and CI builds.
Replace RUN-9 sample data and stub actions with FleetViewModel watch snapshots, workspace enrollment, and local drain/resume controls.

Expose the runner section in release builds and cover the presentation-state mapping.
Let ArcBoxTests consume FleetControlClient through the hosted ArcBox target, avoiding Xcode’s duplicate dynamic gRPC package graph.

Handle runner item-selection deep links explicitly so navigation remains exhaustive.
- coordinate authenticated token handoff with local Agent state
- keep Fleet watch and client transport app-scoped
- reconcile unknown outcomes and graceful termination
On macOS 26, any state change inside a fixedSize(vertical: true)
subtree triggers a window-sizing pass that resizes the window — or the
NavigationSplitView content when the window cannot grow — to the
screen's visible-frame height, sliding the sidebar under the title bar
and pushing the account button off-screen. Drop the modifier from the
dynamic error label (it wraps identically without it) and document the
pitfall in AGENTS.md.
Replace the OIDC Authorization Code + PKCE flow with the Better Auth
device-authorization grant: request a device code, open the approval page
in the default browser, and poll the token endpoint per RFC 8628. The
polled access token is an opaque Better Auth session token with a sliding
server-side expiry, sent as the platform API bearer — the token the
platform actually accepts, unblocking fleet enrollment token issuance.

Identity now comes from the provider session endpoint instead of OIDC
userinfo/ID-token claims, and sign-out revokes the session server-side.
The Keychain store self-heals by clearing pre-device-flow token blobs.
PKCE, discovery, code exchange, token refresh, and the custom-scheme
OAuth callback (including its DeepLinkRouter leg) are gone; build
configuration keys are unchanged. The Account pane and runner section
show the confirmation code with reopen-browser and cancel affordances
while approval is pending.
Use an ephemeral cookie-free URLSession for Better Auth requests and remove legacy Better Auth cookies persisted by previous builds.

Add regressions covering session configuration, response cookie isolation, and scoped legacy cookie cleanup.
Prevent concurrent device sign-in tasks, expose recovery for terminal Fleet states, and complete the test-target and cancellation cleanup validated by the full app suite.
…hots

Credential-rejected and detached snapshots ignored loadState, so a
disconnected watch still offered the unenroll recovery action against
a stale snapshot. Extract the unenrolled branch's loadState switch
into connectivityOverride and reuse it for all three terminal cases.
…-auth

# Conflicts:
#	ArcBox.xcodeproj/project.pbxproj
#	ArcBox/App/AppDelegate.swift
#	ArcBox/App/DeepLinkRouter.swift
#	ArcBox/ArcBoxApp.swift
#	ArcBox/Info.plist
#	ArcBox/Models/NavItem.swift
#	ArcBox/Views/Settings/AccountSettingsView.swift
#	ArcBox/Views/Settings/SettingsView.swift
#	ArcBox/Views/SidebarAccountButton.swift
#	Packages/ArcBoxAuth/Sources/ArcBoxAuth/Session/AuthSession+SignIn.swift
#	Packages/ArcBoxAuth/Tests/ArcBoxAuthTests/AuthSessionTests.swift
…eat/run-12-13-runner-details

# Conflicts:
#	ArcBox.xcodeproj/project.pbxproj
#	ArcBox/Views/ContentView.swift
@linear-code

linear-code Bot commented Aug 10, 2026

Copy link
Copy Markdown

RUN-12

RUN-13

@greptile-apps

greptile-apps Bot commented Aug 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces the previous authentication and manual runner paths with device authorization, Fleet Agent enrollment/watch state, Fleet Platform-backed runner details, and a complete This Mac runner interface.

  • Adds Better Auth device authorization and persisted sessions.
  • Adds Fleet control/platform clients, enrollment recovery, live state watching, and runner actions.
  • Adds host details, settings, capacity, identity, and job-history views.
  • Adds extensive authentication, enrollment, state-mapping, and runner-detail tests.

Confidence Score: 4/5

The PR should not merge until runner job history can retrieve or expose pages beyond the first 50 results.

The platform response cursor is saved but never consumed, so machines with more than 50 jobs always present incomplete history despite the API explicitly returning additional-page state.

Files Needing Attention: ArcBox/ViewModels/RunnerPlatformStore.swift

Important Files Changed

Filename Overview
Packages/ArcBoxAuth/Sources/ArcBoxAuth/Session/AuthSession.swift Replaces OIDC token refresh state with Better Auth session restoration, verification, and sign-out behavior.
ArcBox/ViewModels/Fleet/FleetEnrollmentCoordinator.swift Implements the enrollment state machine, cancellation boundaries, post-handoff reconciliation, and recovery states.
ArcBox/ViewModels/Fleet/FleetViewModel.swift Owns Fleet Agent status, reconnecting snapshot watch, mutations, and image-preparation state.
ArcBox/ViewModels/RunnersViewModel.swift Composes authentication, enrollment, live Fleet state, and runner-facing actions into UI state.
ArcBox/ViewModels/RunnerPlatformStore.swift Polls platform host and job data safely across overlapping refreshes, but permanently truncates job history to the first 50 records.
Packages/FleetPlatformClient/Sources/FleetPlatformClient/FleetPlatformClient.swift Adds authenticated Fleet Platform requests with typed response and HTTP error handling.
ArcBox/Services/FleetAgentConnection.swift Manages the local Fleet Agent transport and exposes readiness to runner enrollment.
ArcBox/Views/Runners/RunnersView.swift Adds the main runner list/detail experience and ties platform polling to enrolled machine state.
ArcBox/App/ApplicationCoordinator.swift Wires authentication, Fleet clients, runner state, hosted roots, startup, and shutdown together.

Sequence Diagram

sequenceDiagram
  participant User
  participant Desktop as ArcBox Desktop
  participant Auth as Better Auth
  participant Platform as Fleet Platform
  participant Agent as Local Fleet Agent

  User->>Desktop: Sign in
  Desktop->>Auth: Request device authorization
  Auth-->>Desktop: User code and verification URL
  Desktop->>Auth: Poll for session
  Auth-->>Desktop: Session token
  Desktop->>Platform: Resolve workspaces and machine
  Desktop->>Agent: Enroll using platform-issued token
  Agent-->>Desktop: Stream current runner snapshots
  Desktop->>Platform: Fetch machine details and first job page
  Platform-->>Desktop: Host, jobs, and next cursor
  Desktop-->>User: Runner status and details
Loading

Reviews (1): Last reviewed commit: "Merge remote-tracking branch 'origin/fea..." | Re-trigger Greptile

Comment on lines +147 to +148
cursor: nil,
limit: 50

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Job history drops later pages

When a runner has more than 50 historical jobs, loadSnapshot() always requests cursor: nil and never consumes the returned nextCursor, causing every job after the first page to remain inaccessible.

Knowledge Base Used: ViewModels: MVVM State Layer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants